home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Tools / TASM V5 / SHOW87.PAK / SHOW87.ASM < prev    next >
Encoding:
Assembly Source File  |  1996-02-21  |  43.9 KB  |  1,311 lines

  1. ;***************************************************************
  2. ;* Show87 - (C) Copyright 1988, 1993 by Borland International  *
  3. ;*              Used with permission of author                 *
  4. ;***************************************************************
  5. ;
  6.  title 'Turbo Assembler SHOW87 Program', '8087 State Display'
  7.  page 65,72
  8. ;=============================================================================
  9. ;
  10. ; This a memory resident program to display the present state of an
  11. ; installed 8087 coprocessor.  Once assembled, to execute, type:
  12. ;
  13. ;   SHOW87 [/r]
  14. ;
  15. ; If run without any options, the program executes a DOS shell and can be
  16. ; removed from memory by typing EXIT at any DOS prompt.  If run with the
  17. ; /r option, the progam is made resident and cannot be removed (but uses
  18. ; less memory).  Uses about 5600 bytes of memory with /r, over 8000 without.
  19. ; Requires CONVERT1.INC, CONVERT2.INC, VIDEO1.INC, and VIDEO2.INC on the
  20. ; default drive/path for assembly.
  21. ;
  22. ; The hot key is ALT-7.  Traps interrupt 09H and uses only BIOS routines for
  23. ; display, thus should work on most computers with most software.
  24. ;
  25. ;
  26. ;----------------------------------------------------------------------------
  27. ;8 Ins Ptr  XXXXX | Prec      XX | ST(0) +X.XXXXXXXXXXXXXXXXX +XXXXX XXXXXX S
  28. ;0 Opr Ptr  XXXXX | Round  XXXXX | ST(1) +X.XXXXXXXXXXXXXXXXX +XXXXX XXXXXX H
  29. ;8 Op Code   XXXX | Infin  XXXXX | ST(2) +X.XXXXXXXXXXXXXXXXX +XXXXX XXXXXX O
  30. ;7 Control   XXXX |------------- | ST(3) +X.XXXXXXXXXXXXXXXXX +XXXXX XXXXXX W
  31. ;| Status    XXXX | Cond    XXXX | ST(4)    =XXXXXXXXXXXXXXXX  =XXXX XXXXXX 8
  32. ;S Tag       XXXX | Comp       X | ST(5)    =XXXXXXXXXXXXXXXX  =XXXX XXXXXX 7
  33. ;T ---------------| Test       X | ST(6)    =XXXXXXXXXXXXXXXX  =XXXX XXXXXX |
  34. ;A Stack Top    X | Exam  XXXXXX | ST(7)    =XXXXXXXXXXXXXXXX  =XXXX XXXXXX X
  35. ;T ------------------------------------------------------------------------ X
  36. ;E Except PX UX OX ZX DX IX    Intr Mask PX UX OX ZX DX IX    Ints XXXXXXXX X
  37. ;----------------------------------------------------------------------------
  38. ;
  39. ; Compare: > < = ?
  40. ; Test: + - 0 ?
  41. ; Examine:  +Unorm +NAN -Unorm -NAN +Norm +Infin -Norm -Infin +0 -0
  42. ;           +Dnorm -Dnorm Empty
  43. ; Precision: 24 53 64 ??
  44. ; Rounding:  near Up Down Trunc
  45. ; Infinity:  Proj Affin
  46. ; Interrupts: Enabled Disabled
  47. ;=========================================================================
  48. ;
  49. Ver_Hi          equ     1       ;ones version number
  50. Ver_Lo          equ     10      ;tens version number
  51.  
  52. HotKey          equ     7e00h   ;hot key, Alt-7
  53. StartRow        equ     0       ;screen row offset
  54. StartCol        equ     0       ;screen column offset
  55. Rows            equ     12      ;rows in display
  56. Cols            equ     76      ;columns in display
  57.  
  58. Atr_Bor         equ     07h     ;border attribute
  59. Atr_Mes         equ     70h     ;edge text attribute
  60. Atr_Lin         equ     07h     ;line attribute
  61. Atr_Tex         equ     07h     ;center text attribute
  62. Atr_Set         equ     07h     ;number and settings attribute
  63.  
  64. Sig_Bits        equ     57      ;number of significant bits in real
  65.                                 ;number display
  66.  
  67. ;================================================
  68. ; Main program, execute shell after resetting
  69. ; interrupt 09H.
  70. ;================================================
  71. ;
  72.  
  73. .model TINY
  74. .code
  75. org 100h
  76.  
  77. ;----------------- Program Entry point --------------------------
  78. Entry:
  79.         jmp Init                ;go to initialization
  80.  
  81. ;--- switch stack and set memory allocation
  82.  
  83. Start:
  84.         mov     bx, offset Program_Stack        ;new stack top
  85.         mov     sp, bx                          ;switch to stack
  86.         mov     cl, 4
  87.         shr     bx, cl                          ;make paragraph
  88.         inc     bx                              ;account for extra
  89.  
  90.         test    byte ptr Status, Status1        ;check if resident mode
  91.         jnz     Main1
  92.  
  93.         mov     ah, 4ah                         ;function
  94.         int     21h                             ;execute
  95.  
  96. ;--- save the interrupt data
  97.  
  98. Main1:
  99.         push    bx
  100.         push    es
  101.         mov     ax, 3509h                       ;function and interrupt number
  102.         int     21h
  103.         mov     word ptr Original09, bx         ;save offset
  104.         mov     word ptr Original09+2, es       ;save segment
  105.         pop     es
  106.         pop     bx
  107.  
  108. ;--- load the new interrupt
  109.  
  110.         mov     ax, 2509h                       ;function
  111.         mov     dx, offset Interrupt09          ;entry point offset
  112.         int     21h                             ;execute
  113.  
  114.         test    byte ptr Status, Status1        ;check if resident mode
  115.         jnz     Main3
  116.  
  117. ;--- initialize the EXEC parameter block and enter shell
  118.  
  119.         push    es
  120.         push    ds
  121.         mov     Prog_Off, sp                    ;save stack offset
  122.         mov     Prog_Seg, ss                    ;save stack segment
  123.  
  124.         mov     ax, 4b00h
  125.         mov     bx, offset Parameter_Blk        ;pararmeter block location
  126.         mov     [bx+4], cs                      ;save the present segment
  127.         mov     dx, CmdLoc                      ;program name offset
  128.         mov     ds,cs:[2ch]                     ;             segment
  129.         int     21h
  130.  
  131.         cli
  132.         mov     sp, cs:Prog_Off                 ;restore stack offset
  133.         mov     ss, cs:Prog_Seg                 ;restore stack segment
  134.         sti
  135.         pop     ds
  136.         pop     es
  137.  
  138. ;--- show exit message
  139.  
  140.         sub     al, al
  141.         mov     dx, offset Closemes             ;normal termination message
  142.         jnc     Main2
  143.         mov     al, 0ffh
  144.         mov     dx, offset Errormes             ;error message
  145. Main2 :
  146.         mov     ah, 9                           ;function
  147.         int     21h                             ;show message
  148.  
  149. ;--- finished
  150.  
  151.         push    ax                              ;save return code
  152.         mov     ax, 2509h                       ;function
  153.         lds     dx, Original09                  ;load original interrupt
  154.                                                 ;  location
  155.         int     21h                             ;execute
  156.         pop     ax
  157.  
  158.         mov     ah, 4ch                         ;exit function
  159.         int     21h                             ;execute
  160.  
  161. ;--- resident mode, terminate and stay resident
  162.  
  163. Main3 :
  164.         mov     ax, 3100h                       ;function and return code
  165.         mov     dx, bx                          ;paragraphs to save
  166.         int     21h                             ;execute
  167.  
  168. ;================================================
  169. ; Control recieved through interrupt 09H.
  170.  
  171. Interrupt09 proc far
  172.  
  173. ;--- guard against reentering
  174.  
  175.     cmp    cs:Active, 0            ; is show87 active?
  176.     je    Inter0
  177.     jmp    cs:Original09            ; yes, pass to old handler
  178.  
  179. Inter0:
  180.  
  181. ;--- first call old handler
  182.  
  183.     pushf
  184.         call    cs:Original09
  185.     
  186. ;--- check if activation key is ready
  187.  
  188.     push    ax                              ; save registers
  189.     push    bx
  190.     mov    ah, 01                          ; non-destructive read
  191.     int    16h                             
  192.     jz    Inter1                          ; any characters there?
  193.     cmp    ax, HotKey                      ; check if activation key
  194.     je    Inter2                          ; jump if so
  195.  
  196. Inter1:
  197.     pop    bx                              ; restore registers
  198.     pop    ax
  199.     iret
  200.  
  201. ;;--- hot key was pressed
  202.  
  203. Inter2:
  204.            inc    cs:Active            ; flag active
  205.  
  206.     xor    ah, ah                          ; read and clear
  207.     int    16h                ; get key function
  208.     pop    bx                              ; restore registers
  209.     pop    ax
  210.  
  211. ;--- save stack
  212.  
  213. Inter3 :
  214.         mov     cs:Stack_Seg, ss                ;segment
  215.         mov     cs:Stack_Off, sp                ;offset
  216.  
  217. ;--- switch to local stack
  218.  
  219.         cli
  220.         push    cs
  221.         pop     ss                              ;set to local segment
  222.         mov     sp, offset Local_Stack          ;set to offset
  223.         sti
  224.  
  225. ;--- save registers
  226.         pushf
  227.         push    ax
  228.         push    bx
  229.         push    cx
  230.         push    dx
  231.         push    di
  232.         push    si
  233.         push    Bp
  234.         push    ds
  235.         push    es
  236.  
  237. ;--- initialize
  238.         push    cs
  239.         pop     ds                              ;set data segment
  240.         push    cs
  241.         pop     es                              ;set other data segment
  242.  
  243.         cli
  244.         fnsave  State_Area                      ;save the 8087 state
  245.         fwait                                   ;synchronize
  246.         sti
  247.  
  248.         cld                                     ;normal direction
  249.                                                 
  250.         call    Video_Init                      ;initialize display data
  251.  
  252.         call    Video_Cget                      ;get the cursor location
  253.         mov     CurLoc, dx                      ;save it
  254.  
  255. ;--- save the screen area
  256.         mov     dh, StartRow                    ;first row
  257.         mov     di, offset Save_Area            ;screen save area
  258.  
  259. Inter4 :
  260.         mov     dl, StartCol                    ;first column
  261.  
  262. Inter5 :
  263.         call    Video_Cset                      ;move cursor
  264.  
  265.         mov     ah, 8                           ;function
  266.         mov     bh, Video_Page                  ;get the page
  267.         push    di
  268.         int     10h                             ;execute, get character
  269.         pop     di
  270.         stosw                                   ;store ah and al
  271.         inc     dl                              ;next column
  272.  
  273.         cmp     dl, StartCol+Cols               ;check if past end
  274.         jb      Inter5                          ;loop back if not
  275.         inc     dh                              ;next row
  276.  
  277.         cmp     dh, StartRow+Rows               ;check if past end
  278.         jb      Inter4                          ;loop back if not
  279.  
  280. ;--- show main display
  281.  
  282.         mov     bl, Atr_Set                     ;attribute
  283.         mov     cx, StartRow*256+StartCol       ;upper left corner
  284.         mov     dx, ((StartRow+Rows-1)*256)+StartCol+Cols-1
  285.                                                 ;lower right corner
  286.         call    Video_Cpag                      ;clear screen area
  287.         mov     si, offset Display1             ;main display string
  288.         call    Video_Wstr                      ;write to screen
  289.  
  290. ;--- show stats
  291.  
  292.         call    Display_State                   ;show state
  293.  
  294. ;--- wait for key
  295.  
  296.         mov     dx, ((StartRow+Rows-1)*256)+StartCol+Cols-1
  297.                                                 ;lower right corner
  298.         call    Video_Cset                      ;move cursor there
  299.  
  300.         sub     ah, ah                          ;function number
  301.  
  302.     int    16h                             ;get a key and wait
  303.  
  304. ;--- restore the screen area
  305.  
  306.         mov     dh, StartRow                    ;first row
  307.         mov     si, offset Save_Area            ;screen save area
  308.  
  309. Inter6  :
  310.         mov     dl, StartCol                    ;first column
  311.  
  312. Inter7  :
  313.         call    Video_Cset                      ;move cursor
  314.  
  315.         lodsw                                   ;load character
  316.                                                 ;   and attribute
  317.         mov     bl, ah                          ;attribute
  318.         mov     ah, 9                           ;function
  319.         mov     bh, Video_Page                  ;get the page
  320.         mov     cx, 1                           ;count
  321.         push    si
  322.         int     10h                             ;execute, get character
  323.         pop     si
  324.  
  325.         inc     dl
  326.         cmp     dl, StartCol+Cols               ;check if past end
  327.         jb      Inter7                          ;loop back if not
  328.         inc     dh                              ;next row
  329.  
  330.         cmp     dh, StartRow+Rows               ;check if past end
  331.         jb      Inter6                          ;loop back if not
  332.  
  333. ;--- finished
  334.  
  335.         mov     dx, CurLoc                      ;get cursor location
  336.         call    Video_Cset                      ;set it
  337.  
  338.         frstor  State_Area                      ;restore state
  339.  
  340.         pop     es
  341.         pop     ds
  342.         pop     bp
  343.         pop     si
  344.         pop     di
  345.         pop     dx
  346.         pop     cx
  347.         pop     bx
  348.         pop     ax
  349.         popf
  350.  
  351. ;--- restore original stack
  352.  
  353.         cli
  354.         mov     ss, cs:Stack_Seg                ;segment
  355.         mov     sp, cs:Stack_Off                ;offset
  356.         sti
  357.  
  358. ;--- return from interrupt
  359.  
  360.            mov    cs:Active,0            ;Inactive
  361.     iret
  362.  
  363.         endp                                    ;Interrupt09
  364.  
  365. ;======================================================
  366. ; Display the 8087 state.
  367. ;=======================================================
  368. Display_State proc near
  369.  
  370. ;--- instruction pointer
  371.  
  372.         mov     ax, State_Area+6   ;instruction pointer, lower 16 bits
  373.         mov     bx, State_Area+8   ;                     upper 4 bits
  374.         mov     cl, 12
  375.         shr     bx, cl                          ;put the bits in the bottom
  376.         mov     cx, 5*256+16                    ;display width and base
  377.         mov     dx, 1*256+11                    ;display location offset
  378.         call    Display_Number                  ;display
  379.  
  380. ;--- operand pointer
  381.  
  382.         mov     ax, State_Area+10   ;operand pointer, lower 16 bits
  383.         mov     bx, State_Area+12   ;                 upper 4 bits
  384.         push    cx
  385.         mov     cl, 12
  386.         shr     bx, cl                          ;put the bits in the bottom
  387.         pop     cx
  388.         inc     dh                              ;next row
  389.         call    Display_Number                  ;display
  390.  
  391. ;--- op code
  392.  
  393.         mov     ax, State_Area+8                ;get the op code
  394.         and     ax, 0000011111111111b           ;mask out bits
  395.         or      ax, 1101100000000000b           ;set implicit bits
  396.         sub     bx, bx                          ;clear high word
  397.         mov     ch, 4                           ;new display width
  398.         inc     dh                              ;next row
  399.         inc     dl                              ;next column
  400.         call    Display_Number                  ;display
  401.  
  402. ;--- control word
  403.  
  404.         mov     ax, State_Area                  ;control word
  405.         inc     dh                              ;next row
  406.         call    Display_Number                  ;display
  407.  
  408. ;--- status word
  409.  
  410.         mov     ax, State_Area+2                ;status word
  411.         inc     dh                              ;next row
  412.         call    Display_Number                  ;display
  413.  
  414. ;--- tag word
  415.  
  416.         mov     ax, State_Area+4                ;tag word
  417.         inc     dh                              ;next row
  418.         call    Display_Number                  ;display
  419.  
  420. ;--- stack top
  421.  
  422.         call    Get_Stack                       ;get the stack top
  423.         sub     ah, ah
  424.         add     dx, 0203h                       ;add two to the rows and add
  425.                                                 ;   three to the columns
  426.         mov     cx, 1*256+10                    ;display width and base
  427.         call    Display_Number                  ;display
  428.  
  429. ;--- precision
  430.  
  431.         mov     bl, State_Area+1                ;high word of control
  432.         and     bl, 11b                         ;mask bits
  433.         sub     bh, bh
  434.         mov     cl, 2                           ;width
  435.         mov     dx, 1*256+29                    ;display location offset
  436.         mov     di, offset Dissta3b             ;table
  437.         call    Display_Istr                    ;display string
  438.  
  439. ;--- rounding
  440.  
  441.         mov     bl, byte ptr State_Area+1       ;high word of control
  442.         and     bl, 1100b                       ;mask bits
  443.         sub     bh, bh
  444.         shr     bx, 1
  445.         shr     bx, 1
  446.         mov     cl, 5                           ;width
  447.         inc     dh
  448.         sub     dl, 3                           ;display location offset
  449.         mov     di, offset Dissta4b             ;table
  450.         call    Display_Istr                    ;display string
  451.  
  452. ;--- infinity
  453.  
  454.         mov     bl, byte ptr State_Area+1       ;high word of control
  455.         and     bl, 10000b                      ;mask bit
  456.         sub     bh, bh
  457.         mov     cl, 4
  458.         shr     bx, cl
  459.         mov     cl, 5                           ;width
  460.         inc     dh                              ;next row
  461.         mov     di, offset Dissta5b             ;table
  462.         call    Display_Istr                    ;display string
  463.  
  464. ;--- condition codes
  465.  
  466.         mov     al, byte ptr State_Area+3       ;high byte of status
  467.         call    Adjst_Codes                     ;adjust the condition codes
  468.         sub     bx, bx                          ;clear high word
  469.         mov     cx, 4*256+2                     ;display width and base
  470.         add     dx, 0201h                       ;new location
  471.         call    Display_Number                  ;display
  472.  
  473. ;--- comparison and test
  474.  
  475.         call    Get_Comp                        ;get the index
  476.         mov     cl, 1                           ;width
  477.         add     dx, 0103h                       ;location
  478.         mov     di, offset Dissta1b             ;table
  479.         call    Display_Istr                    ;display string
  480.  
  481.         inc     dh
  482.         mov     di, offset Dissta2b             ;table
  483.         call    Display_Istr                    ;display string
  484.  
  485. ;--- examine
  486.  
  487.         mov     al, byte ptr State_Area+3       ;high byte of status
  488.         inc     dh
  489.         sub     dl, 5                           ;location
  490.         call    Display_Exam                    ;display
  491.  
  492. ;--- exception bit settings
  493.  
  494.         mov     al, byte ptr State_Area+2       ;get the bits
  495.         mov     dx, 10*256+10                   ;display offset
  496.         call    Display_Bits                    ;display
  497.  
  498. ;--- mask bit settings
  499.  
  500.         mov     al, byte ptr State_Area         ;get the bits
  501.         mov     dx, 10*256+41                   ;display offset
  502.         call    Display_Bits                    ;display
  503.  
  504. ;--- interrupts
  505.  
  506.         mov     ax, word ptr State_Area         ;control word
  507.         shl     ax,1                            ;shift bit to high byte
  508.         and     ah, 1b                          ;mask
  509.         mov     bl, ah
  510.         sub     bh, bh
  511.         mov     cl, -8                          ;width
  512.         mov     dx, 10*256+66                   ;display offset
  513.         mov     di, offset Dissta6b             ;table
  514.         call    Display_Istr                    ;display string
  515.  
  516. ;--- show stack data
  517.  
  518.         call    Display_Stack                   ;show stack values
  519.         ret
  520.  
  521. ;--- data
  522.  
  523. Dissta1a db '>',0, '<',0, '=',0, '?',0
  524. Dissta1b dw offset Dissta1a
  525.          dw offset Dissta1a+2
  526.          dw offset Dissta1a+4
  527.          dw offset Dissta1a+6
  528.  
  529. Dissta2a db '+',0, '-',0, '0',0, '?',0
  530. Dissta2b dw offset Dissta2a
  531.          dw offset Dissta2a+2
  532.          dw offset Dissta2a+4
  533.          dw offset Dissta2a+6
  534.  
  535. Dissta3a db '24',0, '??',0, '53',0, '64',0
  536. Dissta3b dw offset Dissta3a
  537.          dw offset Dissta3a+3
  538.          dw offset Dissta3a+6
  539.          dw offset Dissta3a+9
  540.  
  541. Dissta4a db 'Near',0, 'Up',0, 'Down',0, 'Trunc',0
  542. Dissta4b dw offset Dissta4a
  543.          dw offset Dissta4a+5
  544.          dw offset Dissta4a+8
  545.          dw offset Dissta4a+13
  546.  
  547. Dissta5a db 'Proj',0, 'Affin',0
  548. Dissta5b dw offset Dissta5a
  549.          dw offset Dissta5a+5
  550.  
  551. Dissta6a db 'Enabled',0, 'Disabled',0
  552. Dissta6b dw offset Dissta6a
  553.          dw offset Dissta6a+8
  554.  endp   ;Display_State
  555.  
  556. ;================================================
  557. ; Display of the settings of six consecutive
  558. ; bits.
  559. ;
  560. ; In: al= bit pattern; dx= row and column display
  561. ; offset.
  562. ;==================================================
  563. ;
  564. Display_Bits proc near
  565.         mov     ah, al
  566.         mov     bh, 20h                         ;first bit to check
  567.         mov     cx, 6                           ;bits to check
  568.         add     dx, StartRow*256+StartCol       ;real screen location
  569.  
  570. ;--- loop for each bit
  571.  
  572. Disbit1 :
  573.         mov     al, '-'                         ;not set sign
  574.         test    ah, bh                          ;check if set
  575.         jz      Disbit2
  576.         mov     al, '+'                         ;set sign
  577.  
  578. Disbit2  :
  579.         call    Display_Char                     ;display character
  580.         shr     bh,1                             ;shift bit to test
  581.         add     dl, 2                            ;next location
  582.         loop    Disbit1
  583.  
  584.         ret
  585.  endp           ;Display_Bits
  586.  
  587. ;================================================
  588. ; Display the stack values.
  589. ;================================================
  590. Display_Stack proc near
  591.         std
  592.         mov     bx, offset State_Area           ;save area
  593.         add     bx, 14                          ;skip to numbers
  594.         mov     cx, 8                           ;8087 stack entries
  595.         mov     dh, StartRow+1                  ;first display row
  596.  
  597. ;=== display a number
  598.  
  599. Disstk1 :
  600.         push    bx
  601.         push    cx
  602.  
  603.         fld     TBYTE PTR [bx]                  ;load number
  604.  
  605. ;--- get number type or set to empty
  606.  
  607.         push    cx                              ;save stack number
  608.         call    Get_Stack                       ;get the stack top
  609.         mov     cl, al
  610.         mov     ax, word ptr State_Area+4       ;get the tag word
  611.         shl     cl,1                            ;two bits for each tag
  612.         ror     ax, cl                          ;adjust so first tag is
  613.                                                 ;  in low bits
  614.         pop     cx
  615.         mov     ch, 8
  616.         sub     ch, cl
  617.         shl     ch, 1                           ;bits to shift to put set
  618.                                                 ;  tag low
  619.         mov     cl, ch
  620.         shr     ax, cl                          ;tag bits to lower bit
  621.                                                 ;  locations 0 and 1
  622.         and     ax, 11b                         ;mask bits
  623.  
  624. ;--- check type
  625.  
  626.         cmp     ax, 11b                         ;check if empty
  627.         je      Disstk2
  628.  
  629.         fxam                                    ;check number type
  630.         fstsw   Status87                        ;store status
  631.  
  632.         cmp     ax, 10b                         ;check if special
  633.         je      Disstk3                         ;jump if so
  634.  
  635. ;--- normal value
  636.  
  637.         call    Display_Float                   ;display decimal number
  638.         jmp     short Disstk4
  639.  
  640. ;--- empty
  641.  
  642. Disstk2  :
  643.         mov     Status87, 0ffffh                ;set all bits
  644.  
  645. ;--- special number
  646.  
  647. Disstk3   :
  648.         call    Display_Hex                     ;display hexadecimal bit
  649.                                                 ;  pattern
  650.  
  651. ;--- finished with a single stack number
  652.  
  653. Disstk4    :
  654.         mov     al, byte ptr Status87+1         ;high byte of status
  655.         call    Display_Exam                    ;display
  656.         pop     cx
  657.         pop     bx
  658.  
  659.         add     bx, 10                          ;next stack entry
  660.         inc     dh                              ;next row
  661.         loop    Disstk1                         ;loop for each entry
  662.  
  663.         cld
  664.         ret
  665.  endp           ;Display_Stack
  666.  
  667. ;================================================
  668. ; Display a decimal floating point number.
  669. ;
  670. ; In: ST(0)= number; dh= row.
  671. ;
  672. ; Out: dx= row and column one space after number.
  673. ;==================================================
  674. ;
  675. Display_Float proc near
  676.  
  677. ;--- convert number and store
  678.  
  679.         mov     ax, Sig_Bits                    ;number of significant bits
  680.         call    Flt2dec                         ;convert to decimal
  681.         mov     si, offset Number_Store         ;storage for number
  682.         fbstp   Tbyte Ptr [si]                  ;save number string
  683.  
  684. ;--- display the mantissa sign
  685.  
  686.         push    ax                              ;save the exponent
  687.         mov     dl, StartCol+40                 ;column
  688.  
  689.         add     si, 9                           ;goto last byte
  690.         fwait                                   ;let fbstp finish
  691.         lodsb                                   ;get the sign byte
  692.         mov     ah, '+'
  693.         test    al, 80h                         ;check if negative
  694.         jz      Disflt1
  695.         mov     ah, '-'
  696. Disflt1 :
  697.         mov     al, ah                          ;sign
  698.         call    Display_Char                    ;display character
  699.  
  700. ;--- first two digits and decimal point
  701.  
  702.         lodsb
  703.         call    Display_Bhi                     ;high digit
  704.         push    ax
  705.         mov     al, '.'                         ;decimal point
  706.         call    Display_Char                    ;write point
  707.         pop     ax
  708.         call    Display_Blo                     ;low digit
  709.  
  710. ;--- remaining mantissa digits
  711.  
  712.         mov     cx, 8                           ;remaining number of
  713.                                                 ;  packed bytes
  714.  
  715. Disflt2 :
  716.         lodsb
  717.         call    Display_Bhi                     ;high digit
  718.         call    Display_Blo                     ;low digit
  719.         loop    Disflt2
  720.  
  721. ;--- exponent sign
  722.  
  723.         pop     ax
  724.         inc     dl                              ;skip to exponent location
  725.  
  726.         mov     cl, '+'                         ;plus
  727.         add     ax, 17                          ;adjust for decimal point
  728.         jns     Disflt3                         ;jump if not minus
  729.         mov     cl, '-'                         ;minus
  730.         neg     ax
  731. Disflt3 :
  732.         push    ax
  733.         mov     al, cl
  734.         call    Display_Char                    ;display
  735.         pop     ax
  736.  
  737.          ;--- exponent
  738.  
  739.         sub     bx, bx                          ;clear high word
  740.         mov     cx, 5*256+10                    ;load width and base
  741.         call    Display_Number                  ;display
  742.         add     dl, 6                           ;position cursor at end
  743.         ret
  744.  
  745. ;=================================================
  746. ; Display a high packed BCD digit.
  747. ;
  748. ; In: al= packed BCD digits; bl= attribute.
  749. ;==================================================
  750. Display_Bhi proc near
  751.         push    ax
  752.         shr     al, 1
  753.         shr     al, 1
  754.         shr     al, 1
  755.         shr     al, 1                           ;shift the high bits
  756.         add     al, '0'                         ;convert to decimal digit
  757.         call    Display_Char                    ;write point
  758.         pop     ax
  759.         ret
  760.  endp           ;Display_Bhi
  761.  
  762. ;=================================================
  763. ; Display a low packed BCD digit.
  764. ;
  765. ; In: al= packed BCD digits; bl= attribute.
  766. ;==================================================
  767. ;
  768. Display_Blo proc near
  769.         push    ax
  770.         and     al, 0fh                         ;mask relevant bits
  771.         add     al, '0'                         ;convert to decimal digit
  772.         call    Display_Char                    ;write point
  773.         pop     ax
  774.         ret
  775.  endp                   ;Display_Blo
  776.  
  777.  endp                   ;Display_Float
  778.  
  779. ;================================================
  780. ; Display the bit pattern of a floating point
  781. ; number.
  782. ;
  783. ; In: ST(0)= number; dh= row.
  784. ;
  785. ; Out: dx= row and column one space after number.
  786. ;==================================================
  787. ;
  788. Display_Hex proc near
  789.         fstp    Dishex1                         ;store number
  790.         fwait                                   ;wait just in case
  791.  
  792.         mov     al, '='                         ;starting character
  793.         mov     dl, byte ptr StartCol+43        ;column
  794.         call    Display_Char                    ;display
  795.  
  796.         mov     cx, 8                           ;bytes
  797.         lea     si, Dishex1+7                   ;last byte of mantissa
  798.         call    Display_Byts                    ;display
  799.  
  800.         mov     al, '='                         ;starting character
  801.         add     dl, 2                           ;column
  802.         call    Display_Char                    ;display
  803.  
  804.         mov     cx, 2                           ;bytes
  805.         lea     si, Dishex1+9                   ;last byte of exponent
  806.         call    Display_Byts                    ;display
  807.  
  808.         inc     dl                              ;next column
  809.         ret
  810.  
  811. ;--- storage for the tempory real number
  812.  
  813. Dishex1 label Tbyte
  814.         dt ?        ;
  815.  
  816. ;================================================
  817. ; Display backwards bytes.
  818. ;
  819. ; In: si= starting location; cx= bytes.
  820. ;=================================================
  821. ;
  822. Display_Byts proc near
  823.         pushf
  824.         std
  825.         sub     ah, ah                          ;clear high byte
  826.         sub     bx, bx                          ;clear high word
  827.  
  828. Disbys1  :
  829.         lodsb                                   ;load byte
  830.         push    cx
  831.         push    si
  832.         mov     cx, 2*256+16                    ;format
  833.         call    Display_Number                  ;display
  834.         add     dl, 2                           ;next location
  835.         pop     si
  836.         pop     cx
  837.         loop    Disbys1                         ;loop for each byte
  838.         popf
  839.         ret
  840.  endp                   ;Display_Byts
  841.  
  842.  endp                   ;Display_Hex
  843.  
  844. ;================================================
  845. ; Display an FXAM result.
  846. ;
  847. ; In: al= high byte of 8087 status; dx= row and
  848. ; column location.
  849. ;=================================================
  850. ;
  851. Display_Exam proc near
  852.         call    Adjst_Codes                     ;adjust the condition codes
  853.         mov     bx, ax
  854.         mov     cl, 6                           ;width
  855.         mov     di, offset Disexm1b             ;table
  856.         call    Display_Istr                    ;display string
  857.         ret
  858.  
  859. ;--- data
  860.  
  861. Disexm1a db '+Unorm',0, '+NAN',0, '-Unorm',0, '-NAN',0
  862.          db '+Norm',0, '+Infin',0, '-Norm',0, '-Infin',0
  863.          db '+0',0, '-0',0, '+Dnorm',0, '-Dnorm',0, 'Empty',0
  864. Disexm1b dw offset Disexm1a
  865.          dw offset Disexm1a+7
  866.          dw offset Disexm1a+12
  867.          dw offset Disexm1a+19
  868.          dw offset Disexm1a+24
  869.          dw offset Disexm1a+30
  870.          dw offset Disexm1a+37
  871.          dw offset Disexm1a+43
  872.          dw offset Disexm1a+50
  873.          dw offset Disexm1a+70
  874.          dw offset Disexm1a+53
  875.          dw offset Disexm1a+70
  876.          dw offset Disexm1a+56
  877.          dw offset Disexm1a+70
  878.          dw offset Disexm1a+63
  879.          dw offset Disexm1a+70
  880.  
  881.  endp           ;Display_Exam
  882.  
  883. ;================================================
  884. ; Get the stack top number.
  885. ;
  886. ; Out: al= stack number.
  887. ;=================================================
  888. ;
  889. Get_Stack proc near
  890.         mov     al, byte ptr State_Area+3       ;get the high byte
  891.                                                 ;  of the status word
  892.         and     al, 00111000b                   ;mask out stack
  893.         shr     al, 1
  894.         shr     al, 1
  895.         shr     al, 1                           ;adjust
  896.         ret
  897.  endp            ;Get_Stack
  898.  
  899. ;================================================
  900. ; Adjust the condition codes to consecutive bits.
  901. ;
  902. ; In: al= high byte of status.
  903. ; Out: ax= condition codes in consecutive, least
  904. ; significant bit locations.
  905. ;=================================================
  906. ;
  907. Adjst_Codes proc near
  908.         mov     ah, al
  909.         and     al, 00000111b                   ;mask C2 to C0 bits
  910.         and     ah, 01000000b                   ;mask C3 bit
  911.         shr     ah , 1
  912.         shr     ah , 1
  913.         shr     ah , 1                          ;shift bit over
  914.         or      al, ah                          ;combine
  915.         sub     ah, ah
  916.         ret
  917.  endp           ;Adjst_Codes
  918.  
  919. ;================================================
  920. ; Get an index for the comparison and test
  921. ; instructions. Based on the condition codes.
  922. ;
  923. ; Out: bx= index.
  924. ;==================================================
  925. ;
  926. Get_Comp proc near
  927.         sub     bx, bx
  928.         mov     al, State_Area+3                ;high byte of state
  929.         and     al, 01000101b                   ;mask C3 C2 and C0
  930.         cmp     al, 00000000b                   ;check if 0 0 0
  931.         je      Getcom1
  932.         inc     bx
  933.         cmp     al, 00000001b                   ;check if 0 0 1
  934.         je      Getcom1
  935.         inc     bx
  936.         cmp     al, 01000000b                   ;check if 1 0 0
  937.         je      Getcom1
  938.         inc     bx
  939.  
  940. Getcom1:
  941.         ret
  942.  endp           ;Get_Comp
  943.  
  944. ;================================================
  945. ; Display a single character.
  946. ;
  947. ; In: al= character; dx= location.
  948. ;=================================================
  949. ;
  950. Display_Char proc near
  951.         mov     bl, Atr_Set                     ;attribute
  952.         call    Video_Cset                      ;set cursor location
  953.         call    Video_Wchr                      ;write character
  954.         inc     dl                              ;next column
  955.         ret
  956.  endp                   ;Display_Char
  957.  
  958. ;================================================
  959. ; Display a zero padded number to a location.
  960. ;
  961. ; In: bx:ax= number; cl= number base; ch= the
  962. ; display width; dx= location.
  963. ;=================================================
  964. ;
  965. Display_Number proc near
  966.         push    ax
  967.         push    cx
  968.         push    dx
  969.         add     dx, StartRow*256+StartCol       ;real screen location
  970.         call    Video_Cset                      ;move cursor
  971.  
  972.         push    cx
  973.         sub     ch, ch
  974.         mov     dx, bx                          ;high word
  975.         mov     di, offset Number_Store         ;place to store
  976.         call    Convert_Num                     ;convert to string
  977.         pop     cx
  978.  
  979.         mov     al, '0'                         ;pad character
  980.         mov     cl, ch
  981.         sub     ch, ch
  982.         mov     si, di
  983.         call    Video_Wstrr                     ;display number
  984.         pop     dx
  985.         pop     cx
  986.         pop     ax
  987.         ret
  988.  endp           ;Display_Number
  989.  
  990. ;================================================
  991. ; Given an index and a table, displays a space
  992. ; padded string to a location.
  993. ;
  994. ; In: bx= index; di= table offset; cl= width, if
  995. ; negative, the string is right justified instead
  996. ; of left; dx= location.
  997. ;=================================================
  998. ;
  999. Display_Istr proc near
  1000.         push    ax
  1001.         push    bx
  1002.         push    cx
  1003.         push    dx
  1004.         push    si
  1005.  
  1006. ;--- locate cursor
  1007.  
  1008.         add     dx, StartRow*256+StartCol       ;real screen location
  1009.         call    Video_Cset                      ;move cursor
  1010.  
  1011. ;--- display string
  1012.  
  1013.         mov     al, ' '                         ;pad with spaces
  1014.         shl     bx, 1 ;                         ;two bytes for offset
  1015.         sub     ch, ch
  1016.         mov     si, [di+bx]                     ;get the string location
  1017.  
  1018.         cmp     cl, 0
  1019.         jg      Disist1
  1020.  
  1021.         neg     cl                              ;absolute value
  1022.         call    Video_Wstrl                     ;display, left justified
  1023.         jmp     short Disist2
  1024.  
  1025.         Disist1:
  1026.         call    Video_Wstrr                     ;display, right justified
  1027.  
  1028.         Disist2:
  1029.         pop     si
  1030.         pop     dx
  1031.         pop     cx
  1032.         pop     bx
  1033.         pop     ax
  1034.         ret
  1035.  endp           ;Display_Istr
  1036.  
  1037. ;================================================
  1038. ; External files.
  1039.  
  1040.  include Video1.inc
  1041.  include Video2.inc
  1042.  include Convert1.inc
  1043.  include Convert2.inc
  1044.  
  1045. ;================================================
  1046. ; Data.
  1047.  
  1048. ;--- program status
  1049.  
  1050. Status1 equ 01h                                 ;execute in memory
  1051.                                                 ;  resident mode
  1052.  
  1053. Status db 0
  1054.  
  1055. ;--- original interrupt 09H
  1056.  
  1057. Original09 label Dword
  1058.  dw ?                   ;offset
  1059.  dw ?                   ;segment
  1060.  
  1061. ;--- shell parameter block
  1062.  
  1063. Parameter_Blk label Word
  1064.  dw 0                                           ;use default environment
  1065.  dw offset CmdTail                              ;command tail
  1066.  dw ?                                           ;present segment
  1067.  dw -1                                          ;
  1068.  dw -1                                          ;
  1069.  dw -1                                          ;-- no FCB'S
  1070.  dw -1                                          ;
  1071.  
  1072. CmdTail db 0, 13
  1073.  
  1074. ;--- saved stack addresses
  1075.  
  1076. Prog_Off dw ?           ;-- save area through EXEC function
  1077. Prog_Seg dw ?           ;
  1078.  
  1079. Stack_Off dw ?          ;-- save area for alternate int 09
  1080. Stack_Seg dw ?          ;
  1081.  
  1082. ;--- other data
  1083.  
  1084. CmdLoc dw ?             ;offset of command processor in environment
  1085. CurLoc dw ?             ;saved cursor location
  1086. Active dw ?             ;popup window is active
  1087.  
  1088. ;--- main display string
  1089.  
  1090. Display1 label Byte
  1091.  db FrmAtr, Atr_Bor, FrmLoc, StartRow, StartCol, 219
  1092.  db FrmHor, 223, Cols-2, 219, FrmLoc, StartRow+1, StartCol
  1093.  db FrmVer, 219, Rows-2, FrmLoc, StartRow+1, StartCol+Cols-1
  1094.  db FrmVer, 219, Rows-2, FrmLoc, StartRow+Rows-1
  1095.  db StartCol, 219, FrmHor, 220, Cols-2, 219
  1096.  
  1097.  db FrmAtr, Atr_Lin, FrmLoc, StartRow+9, StartCol+2
  1098.  db FrmHor, 196, 72, FrmLoc, StartRow+1, StartCol+32
  1099.  db FrmVer, 179, 8, 193
  1100.  
  1101.  db FrmAtr
  1102.  db Atr_Mes
  1103.  db FrmLoc, StartRow+1, StartCol, '8'
  1104.  db FrmLoc, StartRow+2, StartCol, '0'
  1105.  db FrmLoc, StartRow+3, StartCol, '8'
  1106.  db FrmLoc, StartRow+4, StartCol, '7'
  1107.  db FrmLoc, StartRow+6, StartCol, 'S'
  1108.  db FrmLoc, StartRow+7, StartCol, 'T'
  1109.  db FrmLoc, StartRow+8, StartCol, 'A'
  1110.  db FrmLoc, StartRow+9, StartCol, 'T'
  1111.  db FrmLoc, StartRow+10, StartCol, 'E'
  1112.  
  1113.  db FrmLoc, StartRow+1, StartCol+Cols-1, 'S'
  1114.  db FrmLoc, StartRow+2, StartCol+Cols-1, 'H'
  1115.  db FrmLoc, StartRow+3, StartCol+Cols-1, 'O'
  1116.  db FrmLoc, StartRow+4, StartCol+Cols-1, 'W'
  1117.  db FrmLoc, StartRow+5, StartCol+Cols-1, '8'
  1118.  db FrmLoc, StartRow+6, StartCol+Cols-1, '7'
  1119.  db FrmLoc, StartRow+8, StartCol+Cols-1, Ver_Hi MOD 10+'0'  ;
  1120.  db FrmLoc, StartRow+9, StartCol+Cols-1, Ver_Lo/10+'0'
  1121.  db FrmLoc, StartRow+10, StartCol+Cols-1, Ver_Lo MOD 10+'0' ;
  1122.  
  1123.  db FrmAtr, Atr_Tex
  1124.  db FrmLoc, StartRow+1, StartCol+2, 'Ins Ptr'
  1125.  db FrmLoc, StartRow+2, StartCol+2, 'Opr Ptr'
  1126.  db FrmLoc, StartRow+3, StartCol+2, 'Op Code'
  1127.  db FrmLoc, StartRow+4, StartCol+2, 'Control'
  1128.  db FrmLoc, StartRow+5, StartCol+2, 'Status'
  1129.  db FrmLoc, StartRow+6, StartCol+2, 'Tag'
  1130.  
  1131.  db FrmLoc, StartRow+8, StartCol+2, 'Stack Top'
  1132.  
  1133.  db FrmLoc, StartRow+1, StartCol+19, 'Prec'
  1134.  db FrmLoc, StartRow+2, StartCol+19, 'Round'
  1135.  db FrmLoc, StartRow+3, StartCol+19, 'Infin'
  1136.  
  1137.  db FrmLoc, StartRow+5, StartCol+19, 'Cond'
  1138.  db FrmLoc, StartRow+6, StartCol+19, 'Comp'
  1139.  db FrmLoc, StartRow+7, StartCol+19, 'Test'
  1140.  db FrmLoc, StartRow+8, StartCol+19, 'Exam'
  1141.  
  1142.  db FrmLoc, StartRow+1, StartCol+34, 'ST(0)'
  1143.  db FrmLoc, StartRow+2, StartCol+34, 'ST(1)'
  1144.  db FrmLoc, StartRow+3, StartCol+34, 'ST(2)'
  1145.  db FrmLoc, StartRow+4, StartCol+34, 'ST(3)'
  1146.  db FrmLoc, StartRow+5, StartCol+34, 'ST(4)'
  1147.  db FrmLoc, StartRow+6, StartCol+34, 'ST(5)'
  1148.  db FrmLoc, StartRow+7, StartCol+34, 'ST(6)'
  1149.  db FrmLoc, StartRow+8, StartCol+34, 'ST(7)'
  1150.  
  1151.  db FrmLoc, StartRow+10, StartCol+2, 'Except'
  1152.  db FrmLoc, StartRow+10, StartCol+9, FrmStr
  1153.  dw offset Display2
  1154.  db FrmLoc, StartRow+10, StartCol+30, 'Intr Mask'
  1155.  db FrmLoc, StartRow+10, StartCol+40, FrmStr
  1156.  dw offset Display2
  1157.  db FrmLoc, StartRow+10, StartCol+61, 'Ints'
  1158.  
  1159.  
  1160.  db FrmAtr, Atr_Set
  1161.  db 0
  1162.  
  1163. Display2 db 'P  U  O  Z  D  I', 0
  1164.  
  1165. ;--- exit message
  1166.  
  1167. Closemes db 13,10,'SHOW87 is removed from memory.',13,10,'$'
  1168. Errormes db 13,10,'Error: Could not install SHOW87', 13,10,'$'
  1169.  
  1170. ;================================================
  1171. ; Uninitialized data.
  1172.  
  1173. Save_Area label Byte                            ;screen data
  1174.         org $+(Rows * Cols * 2)
  1175. State_Area label UNKNOWN                        ;area to save the 8087 state
  1176.         org $+94
  1177. Status87 label Word                             ;8087 status storage for
  1178.                                                 ;  checking numbers
  1179.         org $+2
  1180. Number_Store label Byte                         ;storage for decimal
  1181.                                                 ;  number strings
  1182.         org $+11
  1183.         org $+100h
  1184. Local_Stack label Byte                          ;local stack for state display
  1185.         org $+100h
  1186. Program_Stack label Byte                        ;main program stack
  1187.  
  1188.         org offset Save_Area                    ;fix location
  1189.  
  1190. ;================================================
  1191. ; Transient code.  Exists in unitialized data
  1192. ; area, must be executed before the data area is
  1193. ; used.
  1194.  
  1195. ;--- display opening message
  1196.  
  1197. Init :
  1198.         mov     dx, offset Openmes              ;message
  1199.         mov     ah, 9                           ;function
  1200.         int     21h                             ;display
  1201.  
  1202. ;--- check for 80x87 installed
  1203.         call    Installed8087                   ;check for 80x87
  1204.         cmp     ax, 1                           ;ax=1 if 80x87 installed
  1205.         je      Init0                           ; else 80x87 is NOT installed
  1206.         mov     dx, offset No8087mes
  1207.         mov     ah, 9                           ;display message indicating
  1208.         int     21h                             ;that no 80x87 is installed
  1209.         jmp     short Init8
  1210.  
  1211. ;--- find command processor
  1212. Init0 :
  1213.         push    es
  1214.         mov     cx, 8                           ;string length
  1215.         sub     di, di                          ;starting offset of environment
  1216.         mov     es, cs:[2ch]                    ;environment segment
  1217.  
  1218. ;--- loop for each string in the environment
  1219.  
  1220. Init1 :
  1221.         cmp     byte ptr es:[di], 0             ;check if end of environment
  1222.         je      Init8
  1223.  
  1224.         mov     cx, 8                           ;string length
  1225.         mov     si, offset Comspec              ;string location
  1226.  
  1227.         repe
  1228.         cmpsb                                   ;compare bytes
  1229.         je      Init3                           ;jump if found
  1230.  
  1231. Init2 :
  1232.         cmp     byte ptr es:[di-1], 0           ;see if stopped on end
  1233.                                                 ;  of string
  1234.         je      Init1
  1235.         inc     di                              ;next byte
  1236.         jmp     Init2
  1237.  
  1238. Init3  :
  1239.         mov     CmdLoc, di                      ;save location
  1240.         pop     es
  1241.  
  1242. ;--- set resident flag
  1243.  
  1244.         mov     si, 80h                         ;command tail
  1245.         lodsb                                   ;get the length
  1246.         or      al, al                          ;check if none
  1247.         jz      Init6
  1248.         mov     cl, al
  1249.         sub     ch, ch                          ;put count in cx
  1250.  
  1251. ;--- loop through characters in command tail
  1252.  
  1253. Init4 :
  1254.         lodsb                                   ;load next byte
  1255.         cmp     al, '/'                         ;check if switch
  1256.         je      Init7                           ;jump if so
  1257. Init5 :
  1258.         loop    Init4                           ;otherwise loop back
  1259.  
  1260. Init6:
  1261.         jmp     Start
  1262.  
  1263. ;--- found slash
  1264.  
  1265. Init7:
  1266.         dec     cx                              ;reduce count
  1267.         jz      Init6                           ;jump if no more bytes
  1268.  
  1269.         lodsb                                   ;load command character
  1270.         sub     al, 'a'-'A'                     ;convert to upper-case
  1271.         cmp     al, 'R'                         ;check if R
  1272.         jne     Init5                           ;if not, go back to loop
  1273.         xor     Status, Status1                 ;set (or clear) flag
  1274.         jmp     Start
  1275.  
  1276. ;--- could not find COMSPEC=
  1277.  
  1278. Init8:
  1279.         mov     dx, offset Errormes             ;error message
  1280.         mov     ah, 9                           ;function
  1281.         int     21h                             ;show message
  1282.  
  1283.         mov     ax, 4cffh                       ;exit function
  1284.         int     21h                             ;execute
  1285.  
  1286. ;=========================================================
  1287. ;returns true if an 8087 or 80x87 coprocessor is installed
  1288. ;=========================================================
  1289. Installed8087   proc near
  1290.     int    11h                ;get BIOS equipment flags
  1291.     and    ax, 2            ;bit is ON if 80x87 is present
  1292.     shr    ax, 1
  1293.     ret
  1294. Installed8087   endp
  1295.  
  1296. ;--- transient data
  1297.  
  1298. Openmes db 13,10
  1299.         db 'SHOW87, Version '
  1300.         db Ver_Hi MOD 10+'0', '.', Ver_Lo/10+'0', Ver_Lo MOD 10+'0','$'
  1301. No8087mes db 13,10
  1302.           db 'No numeric processor detected',13,10,'$'
  1303.  
  1304. ;--- command environment string
  1305.  
  1306. Comspec db 'COMSPEC='
  1307.  
  1308. END Entry
  1309.  
  1310. 
  1311.